<template>
  <div class="container">
    <MainNav
        :all-categories="allCategories"
        @filter-change="handleFilterChange"
        @login-success="handleLoginSuccess"
        @logout="handleLogout"
    />
    <header class="header">
      <h1 class="site-title">金融简讯</h1>
      <p class="update-time">最后更新: {{ formatTime(latestUpdate) }}</p>
    </header>

    <main class="news-feed" ref="newsFeedRef">
      <article
          v-for="(item, index) in filteredNews"
          :key="item.id"
          class="news-card"
          :class="{ 'highlighted': highlightedId === item.id }"
          :data-id="item.id"
          :ref="el => newsCardsRef[index] = el as HTMLElement | null"
      >
        <div class="mobile-header mobile-only">
          <span class="category-tag" :class="getCategoryClass(item.category)">{{ item.category }}</span>
        </div>

        <div class="news-meta desktop-only">
          <span class="category-tag" :class="getCategoryClass(item.category)">{{ item.category }}</span>
          <time class="news-time">{{ formatTime(item.timestamp) }}</time>
        </div>

        <div class="news-content">
          <h2 class="news-title">{{ item.title }}</h2>
          <div class="news-data">
            <strong>核心：</strong>{{ truncateText(item.coreData, isMobile ? 60 : 80) }}
          </div>
          <div class="news-source">{{ item.source }}</div>
        </div>
        <div class="news-actions">
          <button
              v-if="hasRelations(item)"
              class="relations-btn"
              @click="toggleRelations(item.id)"
              :class="{ 'active': showRelations[item.id] }"
              :aria-expanded="showRelations[item.id]"
          >
            <Icon name="material-symbols:link" class="icon-link" :class="{ 'rotated': showRelations[item.id] }" />
            关联分析
            <span class="count-badge">{{ item.relations?.length }}条</span>
          </button>
        </div>
        <div
            v-if="hasRelations(item) && showRelations[item.id]"
            class="relations-section"
            :style="{ maxHeight: showRelations[item.id] ? '1000px' : '0', opacity: showRelations[item.id] ? 1 : 0 }"
        >
          <div class="relation-groups">
            <div v-if="getRelationsByType(item, 'direct').length > 0" class="relation-group direct-group">
              <div class="group-header" @click="toggleGroupExpand(item.id, 'direct')" :aria-expanded="isGroupExpanded(item.id, 'direct')">
                <span class="group-title">
                  <Icon name="material-symbols:arrow-right" class="direct-icon" />
                  直接影响
                  <span class="count-badge">{{ getRelationsByType(item, 'direct').length }}条</span>
                </span>
                <Icon
                    name="material-symbols:expand-less"
                    class="toggle-icon"
                    v-if="isGroupExpanded(item.id, 'direct')"
                />
                <Icon
                    name="material-symbols:expand-more"
                    class="toggle-icon"
                    v-else
                />
              </div>
              <ul
                  class="relations-list"
                  v-if="isGroupExpanded(item.id, 'direct')"
                  :style="{ maxHeight: isGroupExpanded(item.id, 'direct') ? '500px' : '0', opacity: isGroupExpanded(item.id, 'direct') ? 1 : 0, padding: isGroupExpanded(item.id, 'direct') ? '8px 0 12px 30px' : '0' }"
              >
                <li
                    v-for="rel in getRelationsByType(item, 'direct')"
                    :key="rel.id"
                    class="relation-item direct"
                    @click="highlightRelated(rel.id)"
                    @mouseenter="hoverRelation(rel.id, true)"
                    @mouseleave="hoverRelation(rel.id, false)"
                    :class="{ 'hovered': hoveredRelations[rel.id] }"
                >
                  <div class="relation-connector"></div>
                  <span class="strength-badge" :class="rel.strength">{{ rel.strength }}</span>
                  <span class="relation-desc">{{ rel.desc }}</span>
                  <Icon name="material-symbols:arrow-right-alt" class="relation-icon" />
                </li>
              </ul>
            </div>
            <div v-if="getRelationsByType(item, 'indirect').length > 0" class="relation-group indirect-group">
              <div class="group-header" @click="toggleGroupExpand(item.id, 'indirect')" :aria-expanded="isGroupExpanded(item.id, 'indirect')">
                <span class="group-title">
                  <Icon name="material-symbols:arrow-right-alt" class="indirect-icon" />
                  间接影响
                  <span class="count-badge">{{ getRelationsByType(item, 'indirect').length }}条</span>
                </span>
                <Icon
                    name="material-symbols:expand-less"
                    class="toggle-icon"
                    v-if="isGroupExpanded(item.id, 'indirect')"
                />
                <Icon
                    name="material-symbols:expand-more"
                    class="toggle-icon"
                    v-else
                />
              </div>
              <ul
                  class="relations-list"
                  v-if="isGroupExpanded(item.id, 'indirect')"
                  :style="{ maxHeight: isGroupExpanded(item.id, 'indirect') ? '500px' : '0', opacity: isGroupExpanded(item.id, 'indirect') ? 1 : 0, padding: isGroupExpanded(item.id, 'indirect') ? '8px 0 12px 30px' : '0' }"
              >
                <li
                    v-for="rel in getRelationsByType(item, 'indirect')"
                    :key="rel.id"
                    class="relation-item indirect"
                    @click="highlightRelated(rel.id)"
                    @mouseenter="hoverRelation(rel.id, true)"
                    @mouseleave="hoverRelation(rel.id, false)"
                    :class="{ 'hovered': hoveredRelations[rel.id] }"
                >
                  <div class="relation-connector"></div>
                  <span class="strength-badge" :class="rel.strength">{{ rel.strength }}</span>
                  <span class="relation-desc">{{ rel.desc }}</span>
                  <Icon name="material-symbols:arrow-right-alt" class="relation-icon" />
                </li>
              </ul>
            </div>
          </div>
        </div>
      </article>
      <div v-if="filteredNews.length === 0" class="no-results">
        <Icon name="material-symbols:search-off" class="no-results-icon" />
        没有找到符合条件的新闻，请尝试其他筛选条件。
      </div>
    </main>
    <footer class="footer">
      <MainFooter />
    </footer>
  </div>
</template>

<script setup lang="ts">
import newsData from '../../public/data/news.json';
import MainNav from '@/components/MainNav/MainNav.vue';
import MainFooter from '@/components/Footer/MainFooter.vue';

useHead({
  title: '最新金融资讯与市场分析 - 深度关联',
  titleTemplate: '%s | 金融简讯',
  meta: [
    {
      name: 'description',
      content: '金融简讯提供最新股票、汇率、大宗商品等金融市场资讯，实时更新核心数据与关联分析，助您快速把握市场动态。'
    },
    {
      name: 'keywords',
      content: '金融简讯, 股票资讯, 汇率分析, 大宗商品, 金融市场'
    },
    { name: 'robots', content: 'index, follow' },
    { name: 'viewport', content: 'width=device-width, initial-scale=1.0' },
    { property: 'og:title', content: '最新金融资讯与市场分析 - 深度关联' },
    { property: 'og:type', content: 'website' },
    { property: 'og:url', content: 'https://你的域名/' },
    {
      property: 'og:description',
      content: '金融简讯提供最新股票、汇率、大宗商品等金融市场资讯，实时更新核心数据与关联分析。'
    },
    {
      property: 'og:image',
      content: 'https://你的域名/og-image.jpg'
    },
    { name: 'twitter:card', content: 'summary_large_image' },
    { name: 'twitter:title', content: '最新金融资讯与市场分析 - 深度关联' },
    {
      name: 'twitter:description',
      content: '金融简讯提供最新股票、汇率、大宗商品等金融市场资讯，实时更新核心数据与关联分析。'
    },
    { name: 'twitter:image', content: 'https://你的域名/og-image.jpg' }
  ],
  link: [
    { rel: 'canonical', href: 'https://实际域名/' },
    { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
  ]
})

// 定义新闻相关的接口类型
interface NewsRelation {
  id: string
  type: 'direct' | 'indirect'
  strength: '强' | '中' | '弱'
  desc: string
}

interface NewsItem {
  id: string
  title: string
  category: string
  timestamp: string
  coreData: string
  impact: string
  source: string
  relations?: NewsRelation[]
}

// 定义用户信息接口
interface User {
  id: string;
  name: string;
  email: string;
  avatar: string;
}

// 类型断言：确保newsData符合NewsItem数组类型
const newsList = ref<NewsItem[]>(newsData as any)

// 检测是否为移动设备
const isMobile = ref<boolean>(false)

// 筛选状态
const activeCategory = ref<string>('all')
const selectedDate = ref<string>('')

// 关联项悬停状态管理
const hoveredRelations = ref<Record<string, boolean>>({})

// 定义ref引用
const newsFeedRef = ref<HTMLElement | null>(null)
const newsCardsRef = ref<(HTMLElement | null)[]>([])

// 监听窗口大小变化
const handleResize = () => {
  isMobile.value = window.innerWidth < 768
}

onMounted(() => {
  handleResize() // 初始化
  window.addEventListener('resize', handleResize)

  // 检查本地存储中的登录状态
  const savedUser = localStorage.getItem('userInfo');
  if (savedUser) {
    try {
      userInfo.value = JSON.parse(savedUser);
      isLoggedIn.value = true;
    } catch (e) {
      console.error('Failed to parse saved user info', e);
    }
  }
})

onUnmounted(() => {
  window.removeEventListener('resize', handleResize)
})

// 处理关联项悬停状态
const hoverRelation = (relId: string, isHovered: boolean) => {
  hoveredRelations.value[relId] = isHovered
}

// 处理筛选条件变化
const handleFilterChange = (filters: { category: string; date: string }) => {
  activeCategory.value = filters.category;
  selectedDate.value = filters.date;
}

// 关联分析显示/隐藏状态管理
const showRelations = ref<Record<string, boolean>>({})

// 切换关联分析显示/隐藏
const toggleRelations = (itemId: string) => {
  showRelations.value[itemId] = !showRelations.value[itemId]
}

// 分组展开状态管理（格式：{ "itemId_type": boolean }）
const expandedGroups = ref<Record<string, boolean>>({})

// 切换分组展开/折叠
const toggleGroupExpand = (itemId: string, type: 'direct' | 'indirect') => {
  const key = `${itemId}_${type}`
  expandedGroups.value[key] = !expandedGroups.value[key]
}

// 判断分组是否展开（默认直接影响展开，间接影响折叠）
const isGroupExpanded = (itemId: string, type: 'direct' | 'indirect'): boolean => {
  const key = `${itemId}_${type}`
  // 初始状态：直接影响展开，间接影响折叠
  if (expandedGroups.value[key] === undefined) {
    return type === 'direct'
  }
  return expandedGroups.value[key]
}

// 按类型筛选关联项
const getRelationsByType = (item: NewsItem, type: 'direct' | 'indirect'): NewsRelation[] => {
  return (item.relations || []).filter(rel => rel.type === type)
}

// 判断是否有关联项
const hasRelations = (item: NewsItem): boolean => {
  return (item.relations || []).length > 0
}

// 关联高亮逻辑
const highlightedId = ref<string | null>(null)
const highlightRelated = (id: string) => {
  const tempId = `temp-${id}`
  highlightedId.value = tempId
  setTimeout(() => {
    highlightedId.value = id
    const targetIndex = filteredNews.value.findIndex(item => item.id === id)
    if (targetIndex !== -1 && newsCardsRef.value[targetIndex]) {
      // 明确类型断言为HTMLElement
      (newsCardsRef.value[targetIndex] as HTMLElement).scrollIntoView({
        behavior: 'smooth',
        block: 'nearest'
      })
    }
    setTimeout(() => highlightedId.value = null, 2000)
  }, 100)
}

// 获取所有分类（去重）
const allCategories = computed<string[]>(() => [
  ...new Set(newsList.value.map(item => item.category))
])

// 获取最新更新时间
const latestUpdate = computed<string>(() => {
  const sorted = [...newsList.value].sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime())
  return sorted[0]?.timestamp || new Date().toISOString()
})

// 获取分类的CSS类名
const getCategoryClass = (category: string): string => {
  return category.toLowerCase().replace(/\s+/g, '-')
}

// 格式化时间显示（仅显示时间或简化日期）
const formatTime = (timestamp: string): string => {
  const date = new Date(timestamp)
  const now = new Date()

  // 今天的消息只显示时间
  if (date.toDateString() === now.toDateString()) {
    return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
  }
  // 今年的消息显示月/日 时间
  if (date.getFullYear() === now.getFullYear()) {
    return `${date.getMonth() + 1}/${date.getDate()} ${date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}`
  }
  // 其他显示完整日期
  return date.toLocaleString()
}

// 格式化日期显示
const formatDate = (dateString: string): string => {
  const date = new Date(dateString)
  return date.toLocaleDateString('zh-CN', { year: 'numeric', month: 'long', day: 'numeric' })
}

// 截断文本，过长时显示省略号 - 移动端更短
const truncateText = (text: string, maxLength: number): string => {
  if (!text) return ''
  if (text.length <= maxLength) return text
  return text.substring(0, maxLength) + '...'
}

// 筛选逻辑
const filteredNews = computed<NewsItem[]>(() => {
  return newsList.value.filter(item => {
    // 分类筛选
    const categoryMatch = activeCategory.value === 'all' || item.category === activeCategory.value

    // 日期筛选
    if (selectedDate.value) {
      const itemDate = new Date(item.timestamp).toISOString().split('T')[0]
      return categoryMatch && itemDate === selectedDate.value
    }

    return categoryMatch
  }).sort((a, b) => {
    // 按时间排序，最新的在前
    return new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()
  })
})

// 用户状态管理
const isLoggedIn = ref<boolean>(false);
const userInfo = ref<User>({
  id: '',
  name: '',
  email: '',
  avatar: ''
});

// 处理登录成功
const handleLoginSuccess = (user: User) => {
  isLoggedIn.value = true;
  userInfo.value = user;
};

// 处理退出登录
const handleLogout = () => {
  isLoggedIn.value = false;
  userInfo.value = {
    id: '',
    name: '',
    email: '',
    avatar: ''
  };
};
</script>

<style scoped>
* {
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
  font-family: "Helvetica Neue", Arial, "Hiragino Sans GB", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif;
}

/* 设备显示控制 - 确保移动端元素只在移动设备显示 */
.mobile-only {
  display: none !important;
}

.container {
  max-width: 1000px;
  margin: 0 auto;
  padding: 15px;
  line-height: 1.6;
  color: #333;
  background-color: #f9f9f9;
  min-height: 100vh;
}

/* 页面头部样式 */
.header {
  text-align: center;
  margin-bottom: 20px;
  padding-bottom: 10px;
  border-bottom: 1px solid #eee;
  animation: fadeIn 0.8s ease-out;
}

@keyframes fadeIn {
  from { opacity: 0; transform: translateY(-10px); }
  to { opacity: 1; transform: translateY(0); }
}

.site-title {
  font-size: 2.2rem;
  margin: 0 0 8px 0;
  color: #222;
  position: relative;
  display: inline-block;
  font-weight: 700;
  letter-spacing: -0.5px;
  line-height: 1.2;
}

.site-title::after {
  content: '';
  position: absolute;
  bottom: -5px;
  left: 10%;
  width: 80%;
  height: 3px;
  background: linear-gradient(90deg, transparent, #3498db, transparent);
  border-radius: 3px;
}

.update-time {
  color: #666;
  font-size: 0.9rem;
  margin: 0;
  font-weight: 400;
  letter-spacing: 0.1px;
}

/* 新闻列表样式 */
.news-feed {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.no-results {
  text-align: center;
  padding: 40px 20px;
  color: #777;
  background-color: white;
  border-radius: 8px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.05);
  font-size: 1rem;
  border: 1px dashed #eee;
}

.no-results-icon {
  font-size: 2rem;
  margin-bottom: 15px;
  color: #ccc;
}

.news-card {
  background: white;
  padding: 12px;
  border-radius: 8px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.05);
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  position: relative;
  overflow: hidden;
  border: 1px solid transparent;
}

.news-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 4px;
  height: 100%;
  background: linear-gradient(to bottom, transparent, #e0e0e0, transparent);
  opacity: 0;
  transition: opacity 0.3s ease;
}

.news-card:hover {
  box-shadow: 0 5px 15px rgba(0,0,0,0.08);
  transform: translateX(2px);
  border-color: #f0f0f0;
}

.news-card:hover::before {
  opacity: 1;
}

.news-card.highlighted {
  border-left: 3px solid #3498db;
  background-color: #f8fcff;
  animation: pulse 2s infinite;
}

@keyframes pulse {
  0% { box-shadow: 0 0 0 0 rgba(52, 152, 219, 0.1); }
  70% { box-shadow: 0 0 0 8px rgba(52, 152, 219, 0); }
  100% { box-shadow: 0 0 0 0 rgba(52, 152, 219, 0); }
}

.mobile-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  margin-bottom: 8px;
  padding-bottom: 8px;
  border-bottom: 1px dashed #f0f0f0;
}

.news-meta {
  flex: 0 0 120px;
  padding-right: 10px;
  box-sizing: border-box;
}

.category-tag {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 10px;
  font-weight: 600;
  color: white;
  font-size: 0.8rem;
  margin-bottom: 5px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.1);
  text-shadow: 0 1px 1px rgba(0,0,0,0.1);
  transition: transform 0.2s ease;
  letter-spacing: 0.3px;
}

.category-tag:hover {
  transform: scale(1.05);
}

.category-tag.黄金 { background-color: #d4af37; }
.category-tag.股票 { background-color: #2ecc71; }
.category-tag.汇率 { background-color: #3498db; }
.category-tag.大宗商品 { background-color: #e67e22; }
.category-tag.债券 { background-color: #9b59b6; }
.category-tag.货币政策 { background-color: #e74c3c; }

.news-time {
  color: #777;
  font-size: 0.75rem;
  display: block;
  position: relative;
  padding-left: 12px;
  font-weight: 400;
}

.news-time::before {
  content: '•';
  position: absolute;
  left: 0;
  color: #ccc;
  font-size: 0.6rem;
  top: 50%;
  transform: translateY(-50%);
}

.news-content {
  flex: 1;
  min-width: 0;
}

.news-title {
  margin: 0 0 6px 0;
  font-size: 1.55rem;
  color: #2c3e50;
  transition: color 0.2s ease;
  position: relative;
  padding-left: 5px;
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: -0.2px;
}

.news-title::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  width: 2px;
  background-color: #eee;
  transition: background-color 0.2s ease;
}

.news-card:hover .news-title {
  color: #3498db;
}

.news-card:hover .news-title::before {
  background-color: #3498db;
}

.news-data {
  font-size: 0.9rem;
  margin: 0 0 6px 0;
  position: relative;
  padding-left: 5px;
  line-height: 1.6;
  color: #2c3e50;
  font-weight: 500;
}

.news-source {
  font-size: 0.8rem;
  color: #999;
  margin-top: 5px;
  padding-top: 5px;
  border-top: 1px dashed #f0f0f0;
  font-style: italic;
  font-weight: 400;
}

.news-actions {
  flex: 0 0 120px;
  padding-left: 10px;
  box-sizing: border-box;
  text-align: right;
}

.relations-btn {
  background: none;
  border: 1px solid #e1e4e8;
  color: #3498db;
  padding: 5px 12px;
  border-radius: 6px;
  font-size: 0.85rem;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  position: relative;
  overflow: hidden;
  box-shadow: 0 1px 2px rgba(0,0,0,0.02);
  font-weight: 500;
}

.relations-btn .icon-link {
  transition: transform 0.3s ease;
  font-size: 1.5rem;
}

.relations-btn .icon-link.rotated {
  transform: rotate(45deg);
}


.relations-btn::before {
  content: '';
  position: absolute;
  top: 0;
  left: -100%;
  width: 100%;
  height: 100%;
  background: linear-gradient(90deg, transparent, rgba(52, 152, 219, 0.1), transparent);
  transition: transform 0.6s ease;
}

.relations-btn:hover::before {
  transform: translateX(100%);
}

.relations-btn:hover {
  background-color: #f1f5f9;
  border-color: #cbd5e1;
  transform: translateY(-1px);
  box-shadow: 0 2px 5px rgba(0,0,0,0.05);
}

.relations-btn.active {
  background-color: #3498db;
  color: white;
  border-color: #2980b9;
}

.relations-btn.active:hover {
  background-color: #2980b9;
  box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}

.count-badge {
  font-size: 0.7rem;
  padding: 1px 5px;
  border-radius: 10px;
  background-color: #3498db;
  color: white;
  box-shadow: 0 1px 2px rgba(0,0,0,0.1);
  font-weight: 500;
}

.relations-btn.active .count-badge {
  background-color: rgba(255,255,255,0.2);
  color: white;
}

/* 关联分析区域样式 - 美化版 */
.relations-section {
  width: 100%;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px dashed #e1e4e8;
  font-size: 0.85rem;
  overflow: hidden;
  transition: max-height 0.4s ease, opacity 0.4s ease;
  opacity: 0;
}

.relations-section[style*="opacity: 1"] {
  animation: fadeIn 0.3s ease-out;
}

.relation-groups {
  padding-left: 130px;
  box-sizing: border-box;
}

.relation-group {
  margin-bottom: 15px;
  border-radius: 6px;
  overflow: hidden;
  transition: all 0.3s ease;
  position: relative;
}

/* 添加装饰性的背景效果 */
.relation-group::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 3px;
  opacity: 0.3;
  transition: opacity 0.3s ease;
}

.direct-group {
  background-color: rgba(231, 76, 60, 0.03);
  border: 1px solid rgba(231, 76, 60, 0.1);
}

.direct-group::before {
  background: linear-gradient(to bottom, #e74c3c, #c0392b, #e74c3c);
}

.indirect-group {
  background-color: rgba(127, 140, 141, 0.03);
  border: 1px solid rgba(127, 140, 141, 0.1);
}

.indirect-group::before {
  background: linear-gradient(to bottom, #7f8c8d, #616a6b, #7f8c8d);
}

.relation-group:hover {
  transform: translateX(3px);
  box-shadow: 0 3px 10px rgba(0,0,0,0.05);
}

.relation-group:hover::before {
  opacity: 0.8;
  box-shadow: 0 0 10px rgba(0,0,0,0.1);
}

.group-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 15px;
  cursor: pointer;
  user-select: none;
  transition: all 0.2s ease;
  border-radius: 4px;
  position: relative;
}

.group-header::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 1px;
  background: linear-gradient(to right, transparent, rgba(0,0,0,0.05), transparent);
}

.group-header:hover {
  background-color: rgba(0,0,0,0.02);
  padding-left: 16px;
  padding-right: 16px;
}

.group-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
  transition: color 0.2s ease;
  font-size: 0.95rem;
}

.direct-group .group-title {
  color: #c0392b;
}

.indirect-group .group-title {
  color: #616a6b;
}

.direct-icon {
  color: #e74c3c;
  font-size: 1.1rem;
  transition: transform 0.2s ease, color 0.2s ease;
}

.group-header:hover .direct-icon {
  transform: scale(1.1) translateX(2px);
  color: #c0392b;
}

.indirect-icon {
  color: #7f8c8d;
  font-size: 1.1rem;
  transition: transform 0.2s ease, color 0.2s ease;
}

.group-header:hover .indirect-icon {
  transform: scale(1.1) translateX(2px);
  color: #616a6b;
}

.group-header .count-badge {
  background-color: rgba(0,0,0,0.08);
  color: #666;
  box-shadow: none;
}

.toggle-icon {
  font-size: 1rem;
  color: #999;
  transition: transform 0.2s ease, color 0.2s ease;
}

.group-header:hover .toggle-icon {
  transform: scale(1.2);
  color: #555;
}

.relations-list {
  margin: 0;
  padding: 0;
  list-style: none;
  overflow: hidden;
  transition: max-height 0.4s ease, opacity 0.4s ease, padding 0.4s ease;
  opacity: 0;
  max-height: 0;
}

.relation-item {
  margin: 0;
  padding: 10px 15px 10px 30px;
  display: flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  border-radius: 0;
  transition: all 0.3s ease;
  font-weight: 400;
  line-height: 1.5;
  position: relative;
  border-bottom: 1px solid rgba(0,0,0,0.03);
}

.relation-item:last-child {
  border-bottom: none;
}

/* 连接线样式 - 美化版 */
.relation-connector {
  position: absolute;
  left: 12px;
  top: 0;
  bottom: 0;
  width: 1px;
  z-index: 1;
  background-size: 10px 10px;
  background-repeat: repeat-y;
}

.direct .relation-connector {
  background-color: rgba(231, 76, 60, 0.2);
  background-image: linear-gradient(to bottom, rgba(231, 76, 60, 0.3) 5px, transparent 5px);
}

.indirect .relation-connector {
  background-color: rgba(127, 140, 141, 0.2);
  background-image: linear-gradient(to bottom, rgba(127, 140, 141, 0.3) 5px, transparent 5px);
}

/* 节点样式 - 美化版 */
.relation-item::before {
  content: '';
  position: absolute;
  left: 8px;
  top: 50%;
  transform: translateY(-50%);
  width: 8px;
  height: 8px;
  border-radius: 50%;
  z-index: 2;
  transition: all 0.3s ease;
  box-shadow: 0 0 0 2px rgba(255,255,255,0.8);
  animation: pulseNode 3s infinite;
}

@keyframes pulseNode {
  0% { box-shadow: 0 0 0 0 rgba(255,255,255,0.8); }
  70% { box-shadow: 0 0 0 5px rgba(255,255,255,0); }
  100% { box-shadow: 0 0 0 0 rgba(255,255,255,0); }
}

.direct.relation-item::before {
  background-color: #e74c3c;
}

.indirect.relation-item::before {
  background-color: #7f8c8d;
}

.relation-item:hover {
  background-color: rgba(255,255,255,0.7);
  transform: translateX(3px);
  padding-left: 33px;
}

.relation-item:hover::before {
  transform: translateY(-50%) scale(1.3);
  box-shadow: 0 0 0 3px rgba(255,255,255,0.9);
  animation: none;
}

.direct.relation-item:hover::before {
  background-color: #c0392b;
  box-shadow: 0 0 0 3px rgba(231, 76, 60, 0.2);
}

.indirect.relation-item:hover::before {
  background-color: #616a6b;
  box-shadow: 0 0 0 3px rgba(127, 140, 141, 0.2);
}

/* 悬停状态额外效果 */
.relation-item.hovered {
  background-color: rgba(255,255,255,0.9);
  animation: highlightItem 1.5s infinite;
}

.footer {
  text-align: center;
  margin-top: 40px;
  padding: 25px 15px 15px;
  border-top: 1px solid #eee;
}
@keyframes highlightItem {
  0% { background-color: rgba(255,255,255,0.9); }
  50% { background-color: rgba(255,255,255,0.7); }
  100% { background-color: rgba(255,255,255,0.9); }
}

.strength-badge {
  font-size: 0.7rem;
  padding: 2px 7px;
  border-radius: 4px;
  color: white;
  text-shadow: 0 1px 1px rgba(0,0,0,0.1);
  font-weight: 500;
  box-shadow: 0 1px 2px rgba(0,0,0,0.1);
  white-space: nowrap;
  transition: transform 0.2s ease;
  position: relative;
  overflow: hidden;
}

.strength-badge::after {
  content: '';
  position: absolute;
  top: 0;
  left: -100%;
  width: 100%;
  height: 100%;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
  transition: all 0.6s ease;
}

.relation-item:hover .strength-badge::after {
  left: 100%;
}

.relation-item:hover .strength-badge {
  transform: scale(1.1);
}

.strength-badge.强 {
  background: linear-gradient(90deg, #e74c3c, #c0392b);
}

.strength-badge.中 {
  background: linear-gradient(90deg, #f39c12, #d35400);
}

.strength-badge.弱 {
  background: linear-gradient(90deg, #3498db, #2980b9);
}

.relation-desc {
  flex: 1;
  transition: color 0.2s ease, transform 0.2s ease;
}

.direct.relation-item:hover .relation-desc {
  color: #c0392b;
}

.indirect.relation-item:hover .relation-desc {
  color: #616a6b;
}

.relation-icon {
  color: rgba(0,0,0,0.2);
  font-size: 0.9rem;
  transition: all 0.3s ease;
  transform: translateX(0);
  opacity: 0;
}

.relation-item:hover .relation-icon {
  color: #3498db;
  transform: translateX(5px);
  opacity: 1;
}

/* 响应式样式 */
@media (max-width: 768px) {
  .mobile-only {
    display: block !important;
  }

  .desktop-only {
    display: none !important;
  }

  .container {
    padding: 10px;
  }

  .site-title {
    font-size: 1.8rem;
    letter-spacing: -0.3px;
  }

  .news-card {
    padding: 15px;
    flex-direction: column;
    gap: 10px;
  }

  .news-meta, .news-actions {
    flex: none;
    width: 100%;
    padding: 0;
  }

  .news-actions {
    text-align: left;
    padding-top: 8px;
    border-top: 1px dashed #f0f0f0;
  }

  .relations-btn {
    width: 100%;
    justify-content: center;
    padding: 10px;
    font-size: 0.95rem;
    gap: 8px;
  }

  .relation-groups {
    padding-left: 0;
  }

  .relations-list {
    padding-left: 0;
  }

  .relation-item {
    padding: 10px 15px 10px 30px;
  }

  .relation-item::before {
    left: 10px;
  }

  .relation-connector {
    left: 14px;
  }

  .news-title {
    font-size: 1.4rem;
    margin-bottom: 8px;
    line-height: 1.4;
  }

  .news-data {
    font-size: 0.9rem;
    margin-bottom: 6px;
    line-height: 1.6;
  }
}
</style>
